package mn.idax.exchange.otc.service.impl;


import com.alibaba.fastjson.JSON;
import mn.idax.exchange.common.RedisRepository;
import mn.idax.exchange.otc.constant.CommonConstant;
import mn.idax.exchange.otc.domain.MessageNotifyDTO;
import mn.idax.exchange.otc.domain.PushNotifyMessage;
import mn.idax.exchange.otc.util.I18nUtil;
import mn.idax.exchange.otc.util.LogUtils;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.Broadcaster;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;


@Service
public class RedisService {

    @Autowired
    private StringRedisTemplate redisTemplate;
//    @Autowired
//    private RedisTemplate<String, Serializable> limitRedisTemplate;

    private static volatile RedisRepository redisRepository;

    /**
     *
     * 初始化redis 中的 OTCOrderId
     */
    @PostConstruct
    public void InitOtcOrderId() {
        if (redisTemplate.hasKey(CommonConstant.REDIS_ORDER_ID_KEY)) {
            redisTemplate.delete(CommonConstant.REDIS_ORDER_ID_KEY);
        }
    }
    /**
     *
     * @param redisTemplate
     * @return
     */
    public static RedisRepository getRedisRepository(StringRedisTemplate redisTemplate){
        if(redisRepository == null){
            synchronized (RedisService.class){
                if(redisRepository == null){
                    redisRepository = new RedisRepository(redisTemplate);
                }
            }
        }
        return redisRepository;
    }

    /**
     * getCachedToken
     * @param key
     * @return
     */
    public String getCacheStrValue(String key){
        String cachedToken = getRedisRepository(redisTemplate).get(key);
        LogUtils.debug(this.getClass(),"getCachedToken;"+ cachedToken);

        return cachedToken;
    }

    /**
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Object getHashValue(String key, String hashKey){
        return getRedisRepository(redisTemplate).getHashValues(key,hashKey);
    }


    /**
     * 自增加一
     * @param key
     * @return long
     */
    public long getIncr(String key){
        long id = getRedisRepository(redisTemplate).incr(key);
        LogUtils.debug(this.getClass(),"getCachedToken;"+ id);
        return id;
    }

    /**
     * getHashValue
     * @param key
     * @return
     */
    public Map<String, String> getHashValue(String key){
        return getRedisRepository(redisTemplate).getHashValue(key);
    }



    /**
     * 有效期
     * @param key
     * @param value
     * @param time
     */
    public void setStringExpire(final String key, final String value, final long time){
        getRedisRepository(redisTemplate).setExpire(key,value,time);
    }
    /**
     * @param key
     * @param value
     */
    public void setString(final String key, final String value){
        getRedisRepository(redisTemplate).set(key,value);
    }

    /**
     * key
     * @param key
     * @return boolean
     */
    public boolean exitsKey(String key){
        return getRedisRepository(redisTemplate).exists(key);
    }


    public void boundHashOps(String key,String hkey,String hvalue){
        this.redisTemplate.boundHashOps(key).put(hkey,hvalue);
    }


    /**
     *
     * 功能描述:
     *      设置过期时间
     * @param:
     * @return:
     * @auther: dison
     * @date: 2018/8/27 16:10
     */
    public void setExpire(final String key,  final long time) {
        redisTemplate.execute((RedisCallback<Long>) connection -> {
            RedisSerializer<String> serializer = redisTemplate.getStringSerializer();
            byte[] keys = serializer.serialize(key);
            connection.expire(keys, time);
            return 1L;
        });
    }

    public void delKey(String key){
        getRedisRepository(redisTemplate).del(key);
    }

    /**
     *
     * 功能描述:
     *      推送消息
     * @param:
     * @return:
     * @auther: dison
     * @date: 2018/10/17 9:47
     */
    public void pushMessage(String topic , String message){
        redisTemplate.convertAndSend(topic, message);
    }

    /**
     *
     * 功能描述:
     *      redis消息通知接收并广播
     * @param:
     * @return:
     * @auther: dison
     * @date: 2018/10/17 10:04
     */
    public boolean receiveNotifyMessage(String pushMessage) {
        PushNotifyMessage pushNotifyMessage = JSON.parseObject(pushMessage , PushNotifyMessage.class);
        Broadcaster broadcaster = MessageNotifyService.broadcasterFactory.lookup(pushNotifyMessage.getUserId() , true);
        if (broadcaster.isDestroyed()){
            LogUtils.info(this.getClass() , "pushNotifyMessage failed cause of userId " + pushNotifyMessage.getUserId() + "disconnected");
            return false;
        }
        MessageNotifyDTO message = JSON.parseObject(pushNotifyMessage.getMessage() , MessageNotifyDTO.class);
        String lang = null;
        Collection<AtmosphereResource> atmosphereResources = broadcaster.getAtmosphereResources();
        for (AtmosphereResource atmosphereResource : atmosphereResources) {
            lang = atmosphereResource.getRequest().getParameter("lang");
        }
        message.setBody(I18nUtil.getMessage(message.getBody() , lang,  message.getDynamicParam()));

//        broadcaster.getAtmosphereResources().forEach(s ->{
//            String messageBody = I18nUtil.getMessage(message.getBody() , s.getRequest().getParameter("lang"),  message.getDynamicParam());
//            message.setBody(messageBody);
//        });

        broadcaster.broadcast(JSON.toJSONString(message));
        LogUtils.info(this.getClass(),"atmospherePush finish, bodyMessage is "+ JSON.toJSONString(message));

        return true;
    }

    public boolean isForbideUser(Integer userId) throws IOException {
        String userid = Integer.toString(userId);
        if (redisTemplate.opsForHash().hasKey(CommonConstant.Forbid_Otc_User,userid)){
            return true;
        }
        return false;
    }


}
